home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 2009 Norman Solomon
- * e-mail: historytree.addon@yahoo.com
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the License.
- */
-
- // *******************************************************************************
- // ***** *****
- // ***** CREATES THE KEY DATA STRUCTURES USED BY THE EXTENSION *****
- // ***** ----------------------------------------------------------- *****
- // ***** i.e. Creates gTreeNodes[] and gTabRoots[] using gNodeList[] and *****
- // ***** gOpenTabIDs[] (passed via App storage from "firefoxOverlay.js") *****
- // ***** *****
- // *******************************************************************************
-
- // =====================================================================
- // Called when history is updated (see "historyViewer.js" onLoad() etc)
- // =====================================================================
- function buildFullHistoryTree()
- {
- // Init all vars used in this function
- var tabRoots = new Array();
- var hNode;
- var tNode, treeRoot, rootChild, tabRoot;
- var FFtabID = "";
- var rootTabID = "";
- var added = false;
- var rootNdx = 0;
- var startNdx;
- var prevSessNdx, sessNdx;
-
- // --------------------------------------------------------------
- // Add a gTreeNodes[] sub-tree for every FF Tab in gNodeList[]
- for (var i = 0; i < gNodeList.length; i++)
- {
- // Only process Tab root HistoryNode's
- hNode = gNodeList[i];
- if (hNode.sessHistNdx === 0)
- {
- // Add Tab root TreeNode to end of gTreeNodes[]
- tNode = new TreeNode(null, null, null, BOX_WIDTH, BOX_HEIGHT + 18);
- gTreeNodes.push(tNode);
-
- // Make HistoryNode point to its associated TreeNode
- hNode.treeNodeNdx = gTreeNodes.length - 1;
-
- // Make TreeNode refer to its associated HistoryNode
- tNode.histNode = hNode;
-
- // Set TreeNode Tab isOpenTab prop *** ONLY set for Tab Roots
- tNode.inOpenTab = isOpenTab(hNode.tab);
-
- // Add Tab root to private array (added to gTabRoots[] below)
- tabRoots.push(tNode);
-
- // Add Tab sub-tree - excluding the root
- buildTabSubTreeForNdx(i);
- }
- }
-
- // --------------------------------------------------------------
- // Add open Tab Root nodes to gTabRoots[] in same order as in FF
- // (needed because user can drag and drop FF Tabs into any order)
- for (var i = 0; i < gOpenTabIDs.length; i++)
- {
- // Get tabID for Tab currently open in FF
- FFtabID = gOpenTabIDs[i];
- added = false;
- rootNdx = 0;
-
- // Add a TreeNode root for this open Tab to gTabRoots[]
- while (!added && rootNdx < tabRoots.length)
- {
- tabRoot = tabRoots[rootNdx];
- if (tabRoot.histNode.tab === FFtabID)
- {
- added = true;
- gTabRoots.push(tabRoot);
- }
- else
- {
- rootNdx ++;
- }
- }
- }
-
- // Add closed Tab roots to gTabRoots[] - in the order user opened them
- // These Tabs are NOT available to the user via the FF sessionHistory
- for (var i = 0; i < tabRoots.length; i++)
- {
- tabRoot = tabRoots[i];
- if (!tabRoot.inOpenTab)
- gTabRoots.push(tabRoot);
- }
-
- // -----------------------------------------------------------------
- // Mark TreeNodes that have corresponding open pages in FF, enabling
- // use of different color schemes for drawing closed or open TreeNodes
- startNdx = gNodeList.length - 1;
- for (var i = 0; i < gTabRoots.length; i++)
- {
- tabRoot = gTabRoots[i];
- if (tabRoot.inOpenTab)
- {
- // Get tabID for Tab currently open in FF
- rootTabID = tabRoot.histNode.tab;
- prevSessNdx = null;
-
- // Loop backwards marking each currently open FF web-page
- for (var ndx = startNdx; ndx >= 0; ndx--)
- {
- hNode = gNodeList[ndx];
- sessNdx = hNode.sessHistNdx;
- if ((sessNdx < prevSessNdx || prevSessNdx === null)
- && hNode.tab === rootTabID)
- {
- tNode = gTreeNodes[hNode.treeNodeNdx];
- tNode.isOpenPage = true; // *** SET TreeNode prop
- prevSessNdx = sessNdx;
- }
- }
- }
- }
-
- // --------------------------------------------------------------
- // MUST add dummy root node as FIRST element in gTreeNodes[]
- treeRoot = new TreeNode(null, null, null, BOX_WIDTH, BOX_HEIGHT);
- gTreeNodes.splice(0, 0, treeRoot);
-
- // Set the dummy root node's first child
- rootChild = gTabRoots[0];
- rootChild.parent = treeRoot;
- treeRoot.child = rootChild;
-
- // Set the dummy root node's siblings (if any)
- for (var i = 1; i < gTabRoots.length; i++)
- {
- tabRoot = gTabRoots[i];
- tabRoot.parent = treeRoot;
- rootChild.sibling = tabRoot;
- rootChild = tabRoot;
- }
-
- // ----------------------------------------------------------------
- // Copy all TreeNode pointers - Enables restoration of current tree
- for (var i = 0; i < gTreeNodes.length; i++)
- {
- tNode = gTreeNodes[i];
- tNode.parentBak = tNode.parent;
- tNode.childBak = tNode.child;
- tNode.siblingBak = tNode.sibling;
- }
- }
-
- // ==========================================================
- // Adds a Tab sub-tree - Called from buildFullHistoryTree()
- // ==========================================================
- function buildTabSubTreeForNdx(histNdx)
- {
- // Init vars needed to build tree
- var hNode = gNodeList[histNdx];
- var tabID = hNode.tab;
- var tNode, tpNode, cNode;
- var pHistNode;
- var startNdx = histNdx + 1;
-
- // ---------------------------------------------------
- // Add a matching TreeNode for every HistoryNode
- for (var i = startNdx; i < gNodeList.length; i++)
- {
- // Only process non Tab root HistoryNode's for this Tab
- hNode = gNodeList[i];
- if (hNode.tab === tabID && hNode.sessHistNdx > 0)
- {
- // Add a new TreeNode to end of gTreeNodes[]
- tNode = new TreeNode(null, null, null, BOX_WIDTH, BOX_HEIGHT);
- gTreeNodes.push(tNode);
-
- // Make HistoryNode point to its associated TreeNode
- hNode.treeNodeNdx = gTreeNodes.length - 1;
-
- // Make TreeNode refer to its associated HistoryNode
- tNode.histNode = hNode;
- }
- }
-
- // ---------------------------------------------------
- // Set the parent, child and sibling pointer references
- for (var i = startNdx; i < gNodeList.length; i++)
- {
- // Only process non Tab root HistoryNode's for this Tab
- hNode = gNodeList[i];
- if (hNode.tab === tabID && hNode.sessHistNdx > 0)
- {
- // Get array index for parent
- pHistNode = parentHistNodeFromSessHistNdx
- (hNode.sessHistNdx - 1, i, tabID);
-
- // If parent was found set pointer references
- if (pHistNode !== null)
- {
- // Get child and parent TreeNode's using hNode pointers
- tNode = gTreeNodes[hNode.treeNodeNdx];
- tpNode = gTreeNodes[pHistNode.treeNodeNdx];
-
- // Make this child point to its parent
- tNode.parent = tpNode;
-
- // Set child OR sibling pointer
- if (tpNode.child === null)
- {
- // Make parent point to first child
- tpNode.child = tNode;
- }
- else
- {
- // Get last sibling in parents chain
- cNode = tpNode.child;
- while (cNode.sibling != null)
- cNode = cNode.sibling;
-
- // Set last child's sibling = this child
- cNode.sibling = tNode;
- }
- }
- }
- }
- }
-
- // =========================================================
- // Returns req parent HistoryNode or null if its not found
- // =========================================================
- function parentHistNodeFromSessHistNdx(parentNdx, startNdx, tabID)
- {
- // Search backwards for parent with matching node.sessHistNdx
- var node;
- for (var i = startNdx; i >= 0; i--)
- {
- // Return HistoryNode if parent found
- node = gNodeList[i];
- if (node.sessHistNdx === parentNdx && node.tab === tabID)
- return node;
- }
-
- // Parent NOT found - So return null
- return null;
- }
-
- // ============================================================
- // Returns true if passed HistoryNode.tab is in an open FF tab
- // ============================================================
- function isOpenTab(tabID)
- {
- // Loop down global list of open FF tabID's
- var FFtabID;
- for (var i = 0; i < gOpenTabIDs.length; i++)
- {
- // Return true if passed tabID matches
- FFtabID = gOpenTabIDs[i];
- if (tabID === FFtabID)
- return true;
- }
-
- // Passed HistoryNode.tab is in a closed FF Tab
- return false;
- }